package yb.ecp.fast.user.infra.datainit;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import yb.ecp.fast.infra.infra.log.LogHelper;

import java.io.File;


/**
 * @author wanghao
 * @Description 数据库初始化配置类
 * @date 2018-02-28 14:14
 */
@Configuration
public class DataInitConfig implements InitializingBean {
    /**
     * 脚本文件路径名
     */
    public static final String SCRIPTS = "scripts";
    public static final String TABLE = "tables";
    public static final String DATA = "data";
    public static final String TABLE_SCRIPT = "ius";
    public static final String DATA_SCRIPT = "init";
    public static final String SNAPSHOT = "-SNAPSHOT";
    public static final String TO = "TO";

    /**
     * 是否初始化数据库，默认关闭
     */
    @Value("${fast.db.initFlag:false}")
    private boolean initFlag;

    @Value("${fast.db.initType:init}")
    private String initType;

    /**
     * 数据库类型
     */
    private DatabaseType databaseType;

    @Value("${spring.datasource.driverClassName:notFound}")
    private String driverClassName;

    /**
     * 版本
     */
    @Value("${version:0.0.3-SNAPSHOT}")
    private String version;

    private String ddlPath;

    private String dataPath;

    private String dbVersion;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    private String queryVersionStr;

    public boolean isInitFlag() {
        return initFlag;
    }

    public DatabaseType getDatabaseType() {
        return databaseType;
    }

    public String getVersion() {
        return version;
    }

    public String getDdlPath() {
        return ddlPath;
    }

    public String getDataPath() {
        return dataPath;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 根据driverClassName判断数据库类型
        if ("com.mysql.jdbc.Driver".equals(this.driverClassName)) {
            this.databaseType = DatabaseType.MYSQL;
            this.queryVersionStr = "select version from version_record order by update_time desc limit 1";
        } else if ("oracle.jdbc.driver.OracleDriver".equals(this.driverClassName)) {
            this.databaseType = DatabaseType.ORACLE;
            this.queryVersionStr = "SELECT VERSION FROM (\n" +
                    "SELECT VERSION_RECORD.*,ROWNUM rn FROM VERSION_RECORD ORDER BY UPDATE_TIME DESC\n" +
                    ") WHERE rn = 1";
        }

        if ("update".equals(initType)) {
            // 对数据库进行版本更新
            try {
                dbVersion = jdbcTemplate.queryForObject(queryVersionStr, String.class);
            } catch (Exception e) {
                LogHelper.fatal("cannot find dbVersion", e);
            }

            if (dbVersion == null) {
                // 版本为空时数据库取默认版本
                dbVersion = "0.0.3-SNAPSHOT";
            }
            if (version.equals(dbVersion)) {
                this.initFlag = false;
                LogHelper.monitor("code version & db version match, init scripts will not run!");
            } else {
                version = dbVersion.replaceAll(SNAPSHOT, "") + TO + version.replaceAll(SNAPSHOT, "");
            }
        }

        if (null != this.databaseType) {
            this.ddlPath = SCRIPTS + File.separator
                    + this.databaseType.getType() + File.separator
                    + TABLE + File.separator
                    + TABLE_SCRIPT + "-" + this.version + ".sql";
            this.dataPath = SCRIPTS + File.separator
                    + this.databaseType.getType() + File.separator
                    + DATA + File.separator
                    + DATA_SCRIPT + "-" + this.version + ".sql";
        } else {
            this.initFlag = false;
            LogHelper.monitor("cannot find database type, init scripts will not run!");
        }
        LogHelper.monitor("please check data init config: " + this);
    }

    @Override
    public String toString() {
        return "DataInitConfig{" +
                "initFlag=" + initFlag +
                ", databaseType=" + databaseType +
                ", version='" + version + '\'' +
                ", ddlPath='" + ddlPath + '\'' +
                ", dataPath='" + dataPath + '\'' +
                ", dbVersion='" + dbVersion + '\'' +
                '}';
    }
}
